package com.stu.day17;

/**
 * @author zy
 * @date 2025/2/18 14:33
 */
public class WaitDemo {
    public static void main(String[] args) {
        Box box = new Box();
        Thread product = new Product(box);
        Thread customer = new Customer(box);
        product.setName("生产者");
        customer.setName("消费者");

        product.start();
        customer.start();

    }
}
//1. 定义一个临界资源 - 多个线程竞争的资源
class Box{

    private int content;//box中的数据

    //标志位
    private boolean has;//如果为true,表示box中是存在东西的.

    /**
     * 生产者调用
     * @param content
     */
    public synchronized void setContent(int content) {
        if(has){
            try {
                wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        //正常放一个
        has = true;
        //notify();//随机唤醒一个等待队列上的线程,被唤醒的线程等到cpu调度
        notifyAll();//将等待队列上的所有的线程都唤醒,被唤醒的线程等到cpu调度

        this.content = content;
    }

    /**
     * 消费者调用
     * @return
     */
    public synchronized int getContent() {
        if(!has){//box中是不存在东西
            //进入到同步等待的阻塞状态 - 此线程处于等待队列上,必须要其他线程调用notify或者notifyAll方法才能够被唤醒
            try {
                wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        //正常取一个
        has = false;
        notifyAll();
        return content;
    }
}
/**生产者线程**/
class Product extends Thread{
    private Box box;
    private int i;

    public Product(Box box){
        this.box = box;
    }

    @Override
    public void run() {
        while(true){
            System.out.println(Thread.currentThread().getName()+"放"+(++i)+"个!");
            box.setContent(i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
/**消费者线程**/
class Customer extends Thread{
    private Box box;
    public Customer(Box box) {
        this.box = box;
    }

    @Override
    public void run() {
        while(true) {
            System.out.println(Thread.currentThread().getName() + "取" + box.getContent() + "个");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}